home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
term.exe
/
TERM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-07
|
17KB
|
586 lines
// Author: Patrick Reilly
// ID: 70274,161 (Compuserve)
// Version 1.01
// Contents --------------------------------------------------------------
//
// termbuf::termbuf constructor
// termbuf::~termbuf destructor
// termbuf::setbuf
// termbuf::underflow
// termbuf::overflow
// termbuf::setmap
// termbuf::setWindow
// termbuf::setBackground
// termbuf::setForeground
// termbuf::setAttribute
// termbuf::clearWindow
// termbuf::gotoWindow
// termbuf::initScreen
// termbuf::processKey
//
// Description
//
// Class termbuf is derived from streambuf for use in terminal
// emulation (for telecommunication apps). The key to emulation is
// mapping keystrokes (scan+ascii) to both actions and terminal
// emulation strings. termbuf class does this with the typedef structure
// KeyMap. Certain keystrokes are hardcoded to certain actions
// (ie ascii 30h prints the letter '0' and ^PGDN clears the screen). In
// the KeyMap structure they are then cross-referenced to the emulation
// string for that keycode. For example, the keycode 0x5000 (DOWN key) is
// hardcoded to move the cursor down one line, and (in VT102 emulation)
// softcoded to "\x01B[B". Therefore if you extract the keystroke 'down-
// arrow' you will extract the string "\x01B[B", and if you insert the
// string "\x01B[B" the cursor will move down the screen one row.
//
// End ------------------------------------------------------------------
// Interface Dependencies -----------------------------------------------
#ifndef __TERM_H
#include "term.h"
#endif
#ifndef __BIOS_H
#include <bios.h>
#endif
#ifndef __CTYPE_H
#include <ctype.h>
#endif
#ifndef __STRING_H
#include <string.h>
#endif
// End Interface Dependencies --------------------------------------------
// Constructor //
_Cdecl termbuf::termbuf()
// Summary --------------------------------------------------------------
//
// Constructor for class termbuf.
//
// Functional Description
//
// The two constructors for termbuf are identical. It sets the base
// streambuf class buffer pointers to NULL so that all incoming and out-
// going characters will be forced to call member underflow() and
// overflow(). It sets the key mapping pointers to NULL to indicate that
// no emulation is in effect. It initializes emapbuf to the end of the
// input buffer (mapbuf)+1 and the input put pointer (pmap) to the start
// of the buffer. It fills the mapMatch array with ones to indicate that
// no elements of the KeyMap array have been eliminated by earlier
// entries. It initializes the text_info structure to the current screen
// window, cursor location, and attribute.
//
// End -------------------------------------------------------------------
{
setb(0,0); setp(0,0); setg(0,0,0); // clear pointers.
map = emap = 0;
insLen = keymapsize = 0;
gettextinfo(&ti);
}
// End Constructor //
// Constructor //
_Cdecl termbuf::termbuf(char _FAR *,int)
// Summary --------------------------------------------------------------
//
// Constructor for class termbuf.
//
// Functional Description
//
// The two constructors for termbuf are identical. It sets the base
// streambuf class buffer pointers to NULL so that all incoming and out-
// going characters will be forced to call member underflow() and
// overflow(). It sets the key mapping pointers to NULL to indicate that
// no emulation is in effect. It initializes emapbuf to the end of the
// input buffer (mapbuf)+1 and the input put pointer (pmap) to the start
// of the buffer. It fills the mapMatch array with ones to indicate that
// no elements of the KeyMap array have been eliminated by earlier
// entries. It initializes the text_info structure to the current screen
// window, cursor location, and attribute.
//
// End -------------------------------------------------------------------
{
setb(0,0); setp(0,0); setg(0,0,0);
map = emap = 0;
insLen = keymapsize = 0;
gettextinfo(&ti);
}
// End Constructor //
// Destructor //
_Cdecl termbuf::~termbuf()
// Summary --------------------------------------------------------------
//
// Vanilla destructor.
//
// End ------------------------------------------------------------------
{
}
// Member Function //
streambuf _FAR * _Cdecl termbuf::setbuf(signed char _FAR *,int)
// Summary --------------------------------------------------------------
//
// Overloaded base member.
//
// Functional Description
//
// This member is overloaded because a streambuf buffer is not
// maintained in the conventional manner.
//
// End ------------------------------------------------------------------
{
return this;
}
// End Member Function //
// Member Function //
int _Cdecl termbuf::underflow()
// Summary --------------------------------------------------------------
//
// Overloaded member called when extraction fails.
//
// Functional Description
//
// Extraction takes place under one of two conditions: 1) the streambuf
// 'get' buffer is empty and you need to get a character from the keyboard,
// or 2) you previously extracted from the keyboard an are getting
// subsequent chars from a multi-character emulation (ie one keystroke
// equates to 2+ emulation chars). If underflow() is called with the get
// buffer empty, it will call bioskey(0) to wait for a keystroke response
// from the user. It then searches the KeyMap array for a matching entry.
// If one is not found, it loops back for another key. If a match is found,
// the streambuf get pointers are set to the emulation string that
// corresponds to that keystroke. This way, subsequent extraction will
// read all of the emulation string before underflow() is called again.
// If the KeyMap pointer is NULL (no emulation), each keystroke is
// returned with no translation.
//
// End ------------------------------------------------------------------
{
char *p,*e;
int x,lo,hi,i;
if(!map) // no emulation
{
setb(&noMap,&noMap+1);
setg(&noMap,&noMap,&noMap+1);
noMap = bioskey(0) & 0xFF;
return (int)noMap;
}
while(1)
{
x = bioskey(0);
// perform binary search for keycode //
for(lo = 0,hi = keymapsize-1; lo != hi;)
{
i = lo+(hi-lo)/2;
if(map[i].keycode == x) break;
else if(map[i].keycode < x) lo = i;
else hi = i;
}
if(map[i].keycode == x) break;
}
p = map[i].string;
for(e = p; *e; e++);
// set the get and buffer pointers to the emulation string //
setb(p,e);
setg(p,p,e);
return *p;
}
// End Member Function //
// Member Function //
int _Cdecl termbuf::overflow(int ch)
// Summary --------------------------------------------------------------
//
// Overloaded insertion member.
//
// Functional Description
//
// Since the streambuf 'put' pointers are maintained at NULL, all
// insertion will cause overflow() to be called for each character. There
// are two cases overflow() must handle: emulation is in effect (the KeyMap
// pointer member map is not NULL) or it is not in effect.
// Class termbuf maintains a member mapMatch, which is just an array
// of flags that correspond to each KeyMap element. When a character is
// inserted, overflow() searches all of the KeyMap emulation strings for
// a match. If an element does not match, the corresponding mapMatch flag
// is set to false. If a match IS found and the next character in the
// emulation string is a NULL (end of string), the emulation has been
// completed and processKey() member is called for the corresponding
// keycode and the member returns. If there was no match in any of the
// emulation strings (all elements of mapMatch false), then the insertion
// was unrecognizable and everything is reinitialized.
// If no emulation is in effect (KeyMap pointer member map is NULL), the
// character inserted is sent to processKey().
//
// NOTE:
//
// Please note that insertion emulation is performed as follows: an
// inserted string is correlated to a keycode in the